﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using Sistema_Totem.Logica.Excepciones;
using Sistema_Totem.Logica.Clases;

namespace Sistema_Totem.Datos.SqlServer
{
    public class SqlServerRequerimiento
    {

        #region  Listar Requerimientos
        /// <summary>
        /// Funcion para obtener desde la base de datos la lista de Requerimientos asociados a un
        /// proyecto activo.
        /// </summary>
        /// <param name="idProyecto">Id del proyecto activo</param>
        /// <returns="requerimientos">Lista de los Requerimientos</returns>
        public List<Requerimiento> ListarRequerimientos(int idProyecto)
        {
            List<string> variables = new List<string>();
            List<string> valores = new List<string>();
            List<Requerimiento> requerimientos = new List<Requerimiento>();

            variables.Add("idProyecto");
            valores.Add(idProyecto.ToString());

            Conexion conexion = new Conexion();

            SqlDataReader reader = BuscarData(conexion, "[dbo].[ListarRequerimientos]", variables, valores);

            while (reader.Read())
            {
                Requerimiento requerimiento = new Requerimiento(Convert.ToInt32(reader.GetDecimal(0)), reader.GetString(1));
                requerimientos.Add(requerimiento);
            }

            conexion.CerrarConexionBd();
            return requerimientos;
        }

        #endregion Listar Requerimientos
        
        #region Listar Elementos
        /// <summary>
        /// Funcion que se encarga de obtener de la base de datos la lista de elementos que tiene la plantilla
        /// asignada a Requerimientos para el proyecto activo
        /// </summary>
        /// <param name="idProyecto">El proyecto activo</param>
        /// <returns="elementos">Lista de elementos de la plantilla</returns>
        public List<Elemento> ListarElementos(int idProyecto)
        {
            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            List<Elemento> elementos = new List<Elemento>();

            variables.Add("idProyecto");
            valores.Add(idProyecto.ToString());

            Conexion conexion = new Conexion();

            SqlDataReader reader = BuscarData(conexion, "[dbo].[ListarElemento]", variables, valores);

            while (reader.Read())
            {
                Elemento elemento = new Elemento(Convert.ToInt32(reader.GetDecimal(0)), reader.GetString(1));
                elementos.Add(elemento);
            }

            return elementos;
        }

        #endregion Listar Elementos
        
        #region Buscar Web Controls
        /// <summary>
        /// Buscar Web Controls se encarga de conectarse a la base de datos y traer el Tipo de Control que representa 
        /// cada elemento de interfaz de usuario que va a mostrar por pantalla, desde la plantilla.
        /// </summary>
        /// <param name="nombreElemento">El nombre del elemento para obetener el tipo</param>
        /// <returns=webControl>El tipo de elemento</returns>
        public String BuscarWebControls(String nombreElemento)
        {
            List<String> variables = new List<String>();
            List<String> valores = new List<String>();
            String webControl = "";

            variables.Add("nombreElemento");
            valores.Add(nombreElemento);
       
            Conexion conexion = new Conexion();

            try
            {
                conexion.AbrirConexionBd();

                SqlDataReader reader = BuscarData(conexion, "[dbo].[BuscarWebControls]", variables, valores);

                while (reader.Read())
                {
                    webControl = reader.GetString(0);

                }

                conexion.CerrarConexionBd();
                return webControl;
            }
            catch (Exception e)
            {
                return null;
            }
        }

        #endregion Buscar WebControls

        #region Agregar Requerimiento
        /// <summary>
        /// Funcion para conectarme a la Base de datos y poder agregar la informacion de un Requerimiento
        /// nuevo en ella.
        /// </summary>
        /// <param name="requerimiento">El requerimiento a insertar</param>
        /// <param name="idProyecto">El id del proyecto activo</param>
        /// <returns="resultado">regresa el resultado de la operacion de insercion.</returns>
        public int AgregarRequerimiento(List<String> agregables, int idProyecto, List<int> idsLista)
        {
            List<String> algo = new List<String>();
            Conexion conexion = new Conexion();

            try
            {
                conexion.AbrirConexionBd();
                SqlCommand command = new SqlCommand();
                command.Connection = conexion.ObjetoConexion();
                command.CommandType = System.Data.CommandType.StoredProcedure;
                command.CommandText = "[dbo].[InsertarRequerimiento]";
                command.CommandTimeout = 10;

                command.Parameters.AddWithValue("@codReq", "TotemReq");
                command.Parameters.AddWithValue("@idProyecto", idProyecto);

                SqlDataReader reader = command.ExecuteReader();
                conexion.CerrarConexionBd();
                
                for (int i =0 ; i < idsLista.Count(); i++ )
                {
                    conexion.AbrirConexionBd();
                    SqlCommand command2 = new SqlCommand();
                    command2.Connection = conexion.ObjetoConexion();
                    command2.CommandType = System.Data.CommandType.StoredProcedure;
                    command2.CommandText = "[dbo].[InsertarPlantillaProyectoElemento]";
                    command2.CommandTimeout = 10;

                    command2.Parameters.AddWithValue("@idProyecto", idProyecto);
                    command2.Parameters.AddWithValue("@idElemento", idsLista[i]);

                    SqlDataReader reader2 = command2.ExecuteReader();
                    conexion.CerrarConexionBd();
                    conexion.AbrirConexionBd();

                    SqlCommand command3 = new SqlCommand();
                    command3.Connection = conexion.ObjetoConexion();
                    command3.CommandType = System.Data.CommandType.StoredProcedure;
                    command3.CommandText = "[dbo].[InsertarContenidoElemento]";
                    command3.CommandTimeout = 10;

                    command3.Parameters.AddWithValue("@valorElemento", agregables[i]);

                    SqlDataReader reader3 = command3.ExecuteReader();
                    conexion.CerrarConexionBd();
                }

                return 0;
                

            }
            catch (Exception e)
            {
                return 1;
            }
        }

        #endregion Agregar Requerimiento

        #region Modificar Requerimiento
        /// <summary>
        /// Funcion para conectarme a la Base de datos y poder modificar la informacion de un Requerimiento
        /// seleccionado previamente
        /// </summary>
        /// <param name="requerimiento">El requerimiento a modificar</param>
        /// <returns="resultado">El resultado de la operacion</returns>
        public int ModificarRequerimiento(Requerimiento requerimiento)
        {
            //List<string> variables = new List<string>();
            //List<string> valores = new List<string>();

            //Conexion conexion = new Conexion();

            //int resultado = EjecutarQuery(conexion, "[dbo].[UpdateRequerimiento]", variables, valores);

            //return resultado;
            return 0;
        }
        #endregion Modificar Requerimiento
        
        #region Eliminar Requerimiento
        /// <summary>
        /// Funcion para conectarme a la Base de datos y poder eliminar la informacion de un Requerimiento
        /// seleccionado previamente.
        /// </summary>
        /// <param name="idRequerimiento">el id del requerimiento a seleccionar</param>
        /// <returns="resultado">el resultado de la operacion</returns>
        public int EliminarRequerimiento(int idRequerimiento)
        {
            List<string> variables = new List<string>();
            List<string> valores = new List<string>();

            variables.Add("idRequerimiento");
            valores.Add(idRequerimiento.ToString());

            Conexion conexion = new Conexion();

            int resultado = EjecutarQuery(conexion, "[dbo].[EliminarRequerimiento]", variables, valores);

            return resultado;
        }

        #endregion Eliminar Requerimiento
        
        #region Consultar Detalle Requerimiento
        /// <summary>
        /// Devuelve el Objeto requerimiento con las listas de atributos cargadas para con sus detalles
        /// </summary>
        /// <param name="idRequerimiento">Id del requerimiento en la BD</param>
        /// <returns="requerimientos">Lista de atributos del requerimiento</returns>
        public List<Requerimiento> ConsultarDetalleRequerimiento(int idRequerimiento)
        {
            List<string> variables = new List<string>();
            List<string> valores = new List<string>();
            List<Requerimiento> requerimientos = new List<Requerimiento>();

            variables.Add("idRequerimiento");
            valores.Add(idRequerimiento.ToString());

            Conexion conexion = new Conexion();
            SqlDataReader reader = BuscarData(conexion, "[dbo].[ConsultarDetalleRequerimiento]", variables, valores);

            while (reader.Read())
            {
                Requerimiento requerimiento = new Requerimiento(reader.GetString(0), reader.GetString(1));
                requerimientos.Add(requerimiento);
            }

            conexion.CerrarConexionBd();
            return requerimientos;
        }

        #endregion Consultar Detalle Requerimiento

        #region Buscar Datos
        /// <summary>
        /// Funcion para ejecutar el stored procedure
        /// </summary>
        /// <param name="conexion">La conexion abierta</param>
        /// <param name="nombreProcedure">Procedimiento a ejecutar</param>
        /// <param name="variablesProcedure">las Variables para el procedure</param>
        /// <param name="valoresVariables">los valores de las variables</param>
        /// <returns="lector">un DataReader que devuelve el resultado del StoredProcedure</returns>
        public SqlDataReader BuscarData(Conexion conexion, string nombreProcedure, List<String> variablesProcedure, List<String> valoresVariables)
        {
            SqlCommand comando = new SqlCommand();
            SqlDataReader lector = null;

            try
            {
                conexion.AbrirConexionBd();
                comando.Connection = conexion.ObjetoConexion();
                comando.CommandType = System.Data.CommandType.StoredProcedure;
                comando.CommandText = nombreProcedure;
                comando.CommandTimeout = 10;

                int i = 0;
                while (i < variablesProcedure.Count())
                {
                    comando.Parameters.AddWithValue(variablesProcedure.ElementAt(i), valoresVariables.ElementAt(i));
                    comando.Parameters[variablesProcedure.ElementAt(i)].Direction = ParameterDirection.Input;
                    i++;
                }

                lector = comando.ExecuteReader();
                return lector;
            }
            catch (ErrorConexionException S)
            {
                Console.WriteLine(S.MensajeError());
                return null;
            }
            catch (Exception E)
            {
                Console.WriteLine(E.Message);
                return null;
            }
        }

        #endregion Buscar Datos

        #region Buscar Datos 2
        /// <summary>
        /// Funcion para ejecutar el stored procedure con un formato distinto
        /// </summary>
        /// <param name="conexion">La conexion abierta</param>
        /// <param name="nombreProcedure">Procedimiento a ejecutar</param>
        /// <param name="variablesProcedure">las Variables para el procedure</param>
        /// <param name="valoresVariables">los valores de las variables</param>
        /// <returns="lector">un DataReader que devuelve el resultado del StoredProcedure</returns>
        public SqlDataReader BuscarData2(Conexion conexion, String nombreProcedure, String variablesProcedure, String valoresVariables)
        {
            SqlCommand comando = new SqlCommand();
            SqlDataReader lector = null;

            try
            {
                comando.Connection = conexion.ObjetoConexion(); 
                comando.CommandType = System.Data.CommandType.StoredProcedure;
                comando.CommandText = nombreProcedure;  
                comando.CommandTimeout = 10;

                comando.Parameters.AddWithValue(variablesProcedure, valoresVariables);
                comando.Parameters[variablesProcedure].Direction = ParameterDirection.Input;

                lector = comando.ExecuteReader();

                return lector;
            }
            catch (ErrorConexionException S)
            {
                return null;
            }
            catch (Exception E)
            {
                return null;
            }
        }

        #endregion Buscar Datos 2

        #region Ejecutar Query
        /// <summary>
        /// Funcion para ejecutar una query
        /// </summary>
        /// <param name="conexion">La conexion abierta</param>
        /// <param name="nombreProcedure">Procedimiento a ejecutar</param>
        /// <param name="variablesProcedure">las Variables para el procedure</param>
        /// <param name="valoresVariables">los valores de las variables</param>
        /// <returns="lector">un DataReader que devuelve el resultado del StoredProcedure</returns>
        public int EjecutarQuery(Conexion conexion, string nombreProcedure, List<string> variablesProcedure, List<string> valoresVariables)
        {
            SqlCommand comando = new SqlCommand();

            try
            {
                conexion.AbrirConexionBd();
               
                comando.Connection = conexion.ObjetoConexion();
                comando.CommandType = System.Data.CommandType.StoredProcedure;
                comando.CommandText = nombreProcedure;
                comando.CommandTimeout = 10;

                int i = 0;
                while (i < variablesProcedure.Count())
                {
                    comando.Parameters.AddWithValue(variablesProcedure.ElementAt(i), valoresVariables.ElementAt(i));
                    comando.Parameters[variablesProcedure.ElementAt(i)].Direction = ParameterDirection.Input;
                    i++;
                }

                comando.ExecuteScalar();
                return 1;
            }

            catch (ErrorConexionException S)
            {
                Console.WriteLine(S.MensajeError());
                return -1;
            }

            catch (Exception E)
            {
                Console.WriteLine(E.Message);
                return -2;
            }

            finally
            {
                conexion.CerrarConexionBd();
            }
        }

        #endregion Ejecutar Query

        #region Recuperar Hijos
        /// <summary>
        /// Funcion para obtener de la base de datos la lista de elementos hijos contenidos
        /// en una DropDown, o radioButton, etc.
        /// </summary>
        /// <param name="IdPadre">el ID del componente padre en la Base de datos</param>
        /// <returns="hijos">Lista de los hijos del componente padre</returns>
        public List<String> RecuperarHijos(int IdPadre)
        {
            List<String> hijos = new List<String>();
            Conexion conexion = new Conexion();

            try
            {
                conexion.AbrirConexionBd();
                SqlCommand command = new SqlCommand();
                command.Connection = conexion.ObjetoConexion();
                command.CommandType = System.Data.CommandType.StoredProcedure;
                command.CommandText = "[dbo].[BuscarHijos]";
                command.CommandTimeout = 10;

                command.Parameters.AddWithValue("@idPadre", IdPadre);

                SqlDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    hijos.Add(reader.GetString(0));
                }

                conexion.CerrarConexionBd();
                return hijos;
            }
            catch (Exception e)
            {
                return null;
            }
        }

        #endregion Recuperar Hijos
   
    }
}